package cn.fotoit.product.aop;

import cn.fotoit.product.system.entity.User;
import cn.fotoit.product.system.entity.UserLog;
import cn.fotoit.product.system.service.UserLogService;
import cn.fotoit.product.system.service.UserService;
import cn.fotoit.product.util.LogInfo;
import com.alibaba.fastjson.JSON;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


/**
 * 日志aop 记录@LogIfo("用户登陆") 的日志
 */
@Aspect
@Component
public class LogAop {

    @Autowired
    private UserLogService userLogService;


    @Autowired
    private UserService userService;

    @Around("execution(* cn.fotoit.product.*.controller.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint pjd) throws Throwable {

        Signature signature = pjd.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        LogInfo annotation = targetMethod.getAnnotation(LogInfo.class);
        //没有注解@LogInfo 的方法直接调用
        if (annotation == null) {
            return pjd.proceed();
        }
        String name = annotation.info();
        boolean saveRequestData = annotation.saveRequestData();
        boolean saveResponseData = annotation.saveResponseData();
        //登陆和未登录用户请求的
        Object[] args = pjd.getArgs();
        Object proceed = pjd.proceed();
        Subject subject = SecurityUtils.getSubject();
        //认证过或通过记住我登录的
        if (subject.isAuthenticated() || subject.isRemembered()) {
            Integer userId = (Integer) subject.getPrincipal();
            User user = userService.findById(userId);
            UserLog userLog = new UserLog(name, user.getId(), user.getNickName(), annotation.type());
            if (saveRequestData) {
                userLog.setRequestData(JSON.toJSONString(args));
            }
            if (saveResponseData) {
                userLog.setResponseData(JSON.toJSONString(proceed));
            }
            userLogService.add(userLog);
        } else {
            UserLog userLog = new UserLog(name, null, "", annotation.type());
            if (saveRequestData) {
                userLog.setRequestData(JSON.toJSONString(args));
            }
            if (saveResponseData) {
                userLog.setResponseData(JSON.toJSONString(proceed));
            }
            userLogService.add(userLog);
        }

        return proceed;
    }
}
